from stuff import cli


class RPyCRegistryServer(cli.Main):
    mode = "UDP"
    port = 18811
    logfile = None
    quiet = False
    timeout = 5 * 60
    
    @cli.switch("m", "mode", arg=cli.OneOfStr("UDP", "TCP"))
    def set_mode(self, mode = mode):
        """set the service mode"""
        self.mode = mode
    
    @cli.switch("p", "port", arg=cli.Range(int, 0, 65535))
    def set_port(self, port = port):
        """set a custom TCP/UDP port"""
        self.port = port

    @cli.switch("logfile", arg=cli.OutputFile())
    def set_logfile(self, logfile = logfile):
        """set a custom logfile"""
        self.logfile = logfile

    @cli.switch("q", "quiet")
    def set_quiet(self):
        """quiet mode (no logging)"""
        self.quiet = True
    
    @cli.switch("timeout", arg=int)
    def set_timeout(self, timeout = timeout):
        """sets a custom pruning timeout"""
        self.timeout = timeout
    
    def main(self):
        if self.mode == "UDP":
            server = UDPRegistryServer(port = self.port,  
                pruning_timeout = self.timeout)
        elif self.mode == "TCP":
            server = TCPRegistryServer(port = self.port, 
                pruning_timeout = self.pruning_timeout)
        
        server.logger.quiet = self.quiet
        if self.logfile:
            server.logger.console = open(self.logfile)
        
        server.start()

class RPyCClassicServer(cli.Main):
    mode = "threaded"
    port = 18812
    logfile = None
    quiet = False
    regtype = "UDP"
    regport = 18812
    reghost = None
    
    @cli.switch("m", "mode", arg=cli.OneOfStr("threaded", "forking", "stdio"))
    def set_mode(self, mode = mode):
        """set the serving mode"""
        self.mode = mode
        
    @cli.switch("p", "port", arg=cli.Range(0, 65535))
    def set_port(self, port = port):
        """set a custom TCP/UDP port"""
        self.port = port

    @cli.switch("logfile", arg=cli.OutputFile())
    def set_logfile(self, logfile = logfile):
        """set a custom logfile"""
        self.logfile = logfile

    @cli.switch("q", "quiet")
    def set_quiet(self):
        """quiet mode (no logging)"""
        self.quiet = True   
     
    @cli.switch("registry-type", arg=cli.OneOfStr("TCP", "UDP"))
    def set_reg_type(self, regtype = regtype):
        self.regtype = regtype

    @cli.switch("registry-port", arg=cli.Range(int, 0, 65535))
    def set_reg_port(self, regport = regport):
        self.regport = regport

    @cli.switch("registry-host", arg=str)
    def set_reg_host(self, reghost):
        """the registry host machine. for UDP, the default is '255.255.255.255';
        for TCP, a value is required"""
        self.reghost = reghost
    
    def main(self):
        if self.regtype == "UDP":
            if self.reghost is None:
                self.reghost = "255.255.255.255"
            self.registrar = UDPRegistryClient(ip = self.reghost, port = self.regport)
        elif self.regtype == "TCP":
            if self.reghost is None:
                raise ValueError("for TCP, must specific registry-host")
            self.registrar = UDPRegistryClient(ip = self.reghost, port = self.regport)
        
        if self.mode == "threaded":
            self.main_threaded()
        elif self.mode == "forking":
            self.main.forking()
        elif self.mode == "stdio":
            self.main_stdio()
    
    def main_stdio(self):
        t = ThreadedServer(SlaveService, port = self.port, reuse_addr = True, 
            registrar = self.registrar)
        t.logger.quiet = self.quiet
        if self.logfile:
            t.logger.console = open(self.logfile)
        t.start()
    
    def main_forking(self):
        t = ForkingServer(SlaveService, port = options.port, reuse_addr = True, 
            registrar = registrar)
        t.logger.quiet = self.quiet
        if self.logfile:
            t.logger.console = open(self.logfile)
        t.start()
    
    def main_stdio(self):
        origstdin = sys.stdin
        origstdout = sys.stdout
        if options.quiet:
            dev = os.devnull
        elif sys.platform == "win32":
            dev = "con:"
        else:
            dev = "/dev/tty"
        try:
            sys.stdin = open(dev, "r")
            sys.stdout = open(dev, "w")
        except (IOError, OSError):
            sys.stdin = open(os.devnull, "r")
            sys.stdout = open(os.devnull, "w")
        conn = rpyc.classic.connect_pipes(origstdin, origstdout)
        try:
            try:
                conn.serve_all()
            except KeyboardInterrupt:
                print "User interrupt!"
        finally:
            conn.close()





